/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/memory
// Copyright( c) 2014.  All Rights Reserved
//
// File:		AEPropertyContainer.h
// Author:		Gianluca Belardelli
// Date:		07/05/2014
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AEPROPERTYCONTAINER_H_
#define _AEPROPERTYCONTAINER_H_

class AEPropertyContainer
{
// Members
public:
	//typedef  AETMap<char *, AEProperty *>	AEPropertyMap;
	typedef  AEMap<char *, AEProperty *>	AEPropertyMap;
protected:
	AEUINT8			m_uiPropertiesCount;
	AEPropertyMap	m_mapProperty;

// Methods
private:
	AEPropertyContainer( const AEPropertyContainer &other );
	AEPropertyContainer& operator=( const AEPropertyContainer &other );

public:
	AE_DLLIMPEXP AEPropertyContainer( AEUINT32 uiSize = 0 );
	AE_DLLIMPEXP ~AEPropertyContainer( void );

	AE_FORCEINLINE AEUINT8 GetPropertiesCount( void ) const;
  
	/// \brief Cleans up any temporary variables in the container and clears all Attributes
	/// \param bTemporariesOnly If set, this will cause Cleanup to only destroy Attributes that
	/// have the ATTR_TEMPORARY behavior set.
	AE_DLLIMPEXP void Cleanup( AEBOOL32 bTemporariesOnly );

	template <typename T> void GetValue( char *lpName, T &tData );

	/// \brief Bind associates a (unique) string name, with the address of a variable in memory.
	/// \param name The string name to associate with this variable.  Must be unique.
	/// \param var The address of the variable associated with this attribute
	/// \param nBehavior The behavior to associate with this attribute
	/// \remark If a attribute of the given name already exists in the AttributeContainer, and
	/// that attribute is of a different type than _T, this results in undefined behavior.  If
	/// they are the same type, then the old attribute is updated with the new variable.
	AE_DLLIMPEXP void AddProperty( AEProperty *lpProperty );

	template <typename T> void Bind( const char *lpName, T *tVar );
	/// \brief removes a specific attribute in the container
	/// \param name the name of the variable to remove.  
	/// \remark If the variable has the ATTR_TEMPORARY behavior set, then it will 
	/// have Destroy() called as well as being removed from the container.
	AE_DLLIMPEXP void Release( const char *lpName );

	/// \brief Returns a Attribute<_T> object, if found in the AttributeContainer
	/// \param name The name of the attribute to search for.
	/// \return A pointer of Attribute<_T> if found, or NULL if not found.
	AE_DLLIMPEXP AEProperty *GetProperty( const char *lpName );

	/// \brief Sets the value of the attribute
	/// \param name The name of the attribute to change
	/// \param val contains the new value to initialize the attribute variable to
	/// \remark The type of this new value must be the same type as the orginially bound
	/// value, otherwise this function will fail and return false.
	/// \return true on success, or false if it fails. Failure typically means that
	/// the type of the data argument is inconsistent with the type of the stored variable.
	template <typename T> void SetValue( char *lpName, const T &tVal );

};

#include "AEPropertyContainer.inl"

#endif // _AEPROPERTYCONTAINER_H_
